using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Xml;
using Pharmacy.Data.Entity;

namespace Pharmacy.Ultilities.Configurations
{
    public partial class DIOConfig
    {
        /// <summary>
        /// Initializes new instance of <see cref="DIOConfig"/>.
        /// </summary>
        /// <author></author>
        /// <history>
        /// 2011.03.25: added xml-doc, changed to use IOHelper.ExecutePath to enable unit testing.
        /// </history>
        public DIOConfig()
        {
            _configFilePath = IOHelper.CombinePath(IOHelper.ExecutePath, "DIOConfig.xml");
            GetLatestDoc(); //cuongnguyen, 2011:02:09: Load DIOConfig.xml for the first time start up DIOConfig object.
        }

        /// <summary>
        /// Initializes new instance of <see cref="DIOConfig"/>.
        /// </summary>
        /// <author></author>
        /// <history>
        /// 2011.03.25: added xml-doc, changed to use IOHelper.ExecutePath to enable unit testing.
        /// </history>
        public DIOConfig(string configFilePath)
        {
            _configFilePath = configFilePath;
            GetLatestDoc(); //cuongnguyen, 2011:02:09: Load DIOConfig.xml for the first time start up DIOConfig object.
        }

        // <summary>
        // Code Area For Common Config
        // Put Config Name You Want to become common config in to IsCommonConfig
        // Author      : vinhvo
        // Create      : 20/12/2010
        // Last Change : 20/12/2010
        // </summary>
        #region Customize For Common Config

        //For Attributes[string sectionName, string attributeName]
        private static bool IsCommonConfig(string sectionName, string attributeName)
        {
            // TO DO: this function always return FALSE ? //cuongnguyen, 2011:02:09
            switch (String.Format("{0}-{1}", sectionName, attributeName))
            {
                default:
                    return false;
            }
        }

        //For Attributes[string sectionName, string entryAttributeKey, string entryAttributeKeyValue, string entryAttributeName]
        private static bool IsCommonConfig(string sectionName, string entryAttributeKey, string entryAttributeKeyValue,
                                           string entryAttributeName)
        {
            string key = String.Format("{0}-{1}-{2}-{3}", sectionName, entryAttributeKey, entryAttributeKeyValue, entryAttributeName);
            List<string> listkey = new List<string>();
            listkey.AddRange(new string[]
                                 {
                                    
                                 });

            return listkey.Contains(key);
        }

        //For This[string sectionName, string entryAttributeKey, string entryAttributeKeyValue]
        private static bool IsCommonConfig(string sectionName, string entryAttributeKey, string entryAttributeKeyValue)
        {
            // TO DO: this function always return FALSE ? //cuongnguyen, 2011:02:09
            switch (String.Format("{0}-{1}-{2}", sectionName, entryAttributeKey, entryAttributeKeyValue))
            {
                default:
                    return false;
            }
        }

        //For This[string key]
        private static bool IsCommonConfig(string key)
        {
            List<string> commonKeys = new List<string>(new string[]
                                                           {
                                                              
                                                           });

            return commonKeys.Contains(key);
        }


        public static void ReloadCommonConfig()
        {
            CommonConfig.IsError = false;
        }

        /// <summary>
        ///   Using for Common Config Read, Save change to Database
        /// </summary>
        public partial class CommonConfig
        {
            private static List<CommonConfig> _list;

            #region Public Vars

            public static bool IsError;
            public string Key;
            public Guid RID;
            public string Value;
            public string attributeName;
            public string entryAttributeKey;
            public string entryAttributeKeyValue;
            public string entryAttributeName;
            public string sectionName;

            #endregion

            /// <summary>
            ///   Get All Common Config From Database
            /// </summary>
            /// <returns></returns>
            public static List<CommonConfig> GetList()
            {
                List<CommonConfig> list = new List<CommonConfig>();
                using (SqlConnection sqlCnn = new SqlConnection(ConfigManager.DIOConfig.ConnectionString))
                {
                    try
                    {
                        sqlCnn.Open();
                        SqlCommand sqlCmd = new SqlCommand(Constant.DIO_CommonConfigSqlSelect, sqlCnn);
                        SqlDataReader sqlReader = sqlCmd.ExecuteReader();
                        while (sqlReader.Read())
                        {
                            CommonConfig config = new CommonConfig();
                            config.RID = (Guid)sqlReader["RID"];
                            config.entryAttributeKey = sqlReader["entryAttributeKey"] == DBNull.Value
                                                           ? null
                                                           : sqlReader["entryAttributeKey"].ToString();
                            config.sectionName = sqlReader["sectionName"] == DBNull.Value
                                                     ? null
                                                     : sqlReader["sectionName"].ToString();
                            config.entryAttributeKeyValue = sqlReader["entryAttributeKeyValue"] == DBNull.Value
                                                                ? null
                                                                : sqlReader["entryAttributeKeyValue"].ToString();
                            config.entryAttributeName = sqlReader["entryAttributeName"] == DBNull.Value
                                                            ? null
                                                            : sqlReader["entryAttributeName"].ToString();
                            config.Key = sqlReader["Key"] == DBNull.Value ? null : sqlReader["Key"].ToString();
                            config.attributeName = sqlReader["attributeName"] == DBNull.Value
                                                       ? null
                                                       : sqlReader["attributeName"].ToString();
                            config.Value = sqlReader["Value"] == DBNull.Value ? null : sqlReader["Value"].ToString();
                            list.Add(config);
                        }
                        IsError = false;
                    }
                    catch (SqlException sqlex)
                    {
                        if (sqlex.Message == "Invalid object name 'DIO_CommonConfig'.")
                        {
                            //Not exist Table
                            //Create Table
                            try
                            {
                                SqlCommand sqlCmdCreate = new SqlCommand(Constant.DIO_CommonConfigSqlCreate, sqlCnn);
                                sqlCmdCreate.ExecuteNonQuery();
                                SqlCommand sqlCmdAlter = new SqlCommand(Constant.DIO_CommonConfigSqlCreateAlterDefault,
                                                                        sqlCnn);
                                sqlCmdAlter.ExecuteNonQuery();
                                IsError = false;
                                list = new List<CommonConfig>();
                            }
                            catch
                            {
                                list = null;
                                IsError = true;
                            }
                        }
                        else
                        {
                            //Pass When Can't Connect to Database
                            //Utilities.NotifyUserUtil.ShowMessageDialogWarning("Can't connect to database to save ");
                            list = null;
                            IsError = true;
                        }
                    }
                }
                return list;
            }

            /// <summary>
            ///   Find Config via Key
            /// </summary>
            /// <param name = "Key"></param>
            /// <returns></returns>
            public static CommonConfig FindKey(string Key)
            {
                if (IsError) return null;
                if (_list == null)
                {
                    _list = GetList();
                }
                if (_list == null) return null;
                CommonConfig ret = null;
                foreach (CommonConfig config in _list)
                {
                    if (config.Key == Key)
                    {
                        ret = config;
                        break;
                    }
                }

                return ret;
            }

            public static CommonConfig FindKey(string sectionName, string entryAttributeKey,
                                                   string entryAttributeKeyValue)
            {
                if (IsError) return null;
                if (_list == null)
                {
                    _list = GetList();
                }
                if (_list == null) return null;
                CommonConfig ret = null;
                foreach (CommonConfig config in _list)
                {
                    if (config.sectionName == sectionName
                        && config.entryAttributeKey == entryAttributeKey
                        && config.entryAttributeKeyValue == entryAttributeKeyValue)
                    {
                        ret = config;
                        break;
                    }
                }

                return ret;
            }

            public static CommonConfig FindKey(string sectionName, string attributeName)
            {
                if (IsError) return null;
                if (_list == null)
                {
                    _list = GetList();
                }
                if (_list == null) return null;
                CommonConfig ret = null;
                foreach (CommonConfig config in _list)
                {
                    if (config.sectionName == sectionName
                        && config.attributeName == attributeName)
                    {
                        ret = config;
                        break;
                    }
                }

                return ret;
            }

            public static CommonConfig FindKey(string sectionName, string entryAttributeKey,
                                                   string entryAttributeKeyValue, string entryAttributeName)
            {
                if (IsError) return null;
                if (_list == null)
                {
                    _list = GetList();
                }
                if (_list == null) return null;
                CommonConfig ret = null;
                foreach (CommonConfig config in _list)
                {
                    if (config.sectionName == sectionName
                        && config.entryAttributeKey == entryAttributeKey
                        && config.entryAttributeKeyValue == entryAttributeKeyValue
                        && config.entryAttributeName == entryAttributeName)
                    {
                        ret = config;
                        break;
                    }
                }

                return ret;
            }

            /// <summary>
            ///   Insert Config To Database, use for Insert new when not exist config on database
            /// </summary>
            /// <param name = "config"></param>
            public static void Insert(CommonConfig config)
            {
                if (IsError) return;
                using (SqlConnection sqlCnn = new SqlConnection(ConfigManager.DIOConfig.ConnectionString))
                {
                    sqlCnn.Open();
                    config.RID = Guid.NewGuid();
                    string strCmd = Constant.DIO_CommonConfigSqlInsert;

                    SqlParameter pRID = new SqlParameter("@RID", config.RID);
                    SqlParameter psectionName = new SqlParameter("@sectionName", config.sectionName);
                    SqlParameter pentryAttributeKey = new SqlParameter("@entryAttributeKey", config.entryAttributeKey);
                    SqlParameter pentryAttributeKeyValue = new SqlParameter("@entryAttributeKeyValue",
                                                                            config.entryAttributeKeyValue);
                    SqlParameter pentryAttributeName = new SqlParameter("@entryAttributeName", config.entryAttributeName);
                    SqlParameter pKey = new SqlParameter("@Key", config.Key);
                    SqlParameter pValue = new SqlParameter("@Value", config.Value);
                    SqlParameter pattributeName = new SqlParameter("@attributeName", config.attributeName);

                    SqlCommand sqlCmd = new SqlCommand(strCmd, sqlCnn);

                    sqlCmd.Parameters.AddRange(new SqlParameter[]
                                                   {
                                                       pRID,
                                                       psectionName,
                                                       pentryAttributeKey,
                                                       pentryAttributeKeyValue,
                                                       pentryAttributeName,
                                                       pKey,
                                                       pValue,
                                                       pattributeName
                                                   });

                    foreach (SqlParameter p in sqlCmd.Parameters)
                    {
                        if (p.Value == null) p.Value = DBNull.Value;
                    }

                    sqlCmd.ExecuteNonQuery();
                    _list.Add(config);
                }
            }

            /// <summary>
            ///   Update config when save
            /// </summary>
            /// <param name = "config"></param>
            public static void Update(CommonConfig config)
            {
                if (IsError) return;
                using (SqlConnection sqlCnn = new SqlConnection(ConfigManager.DIOConfig.ConnectionString))
                {
                    sqlCnn.Open();
                    string strCmd = Constant.DIO_CommonConfigSqlUpdate;
                    SqlParameter pRID = new SqlParameter("@RID", config.RID);
                    SqlParameter pValue = new SqlParameter("@Value", config.Value);

                    SqlCommand sqlCmd = new SqlCommand(strCmd, sqlCnn);

                    sqlCmd.Parameters.AddRange(new SqlParameter[]
                                                   {
                                                       pRID,
                                                       pValue
                                                   });

                    foreach (SqlParameter p in sqlCmd.Parameters)
                    {
                        if (p.Value == null) p.Value = DBNull.Value;
                    }


                    sqlCmd.ExecuteNonQuery();
                    _list.Add(config);
                }
            }
        }

        #endregion

        #region Attribute

        // Get value of attribute with the given name in a section
        // ex: this["log", "active"]

        public class Attribute
        {

            public XmlDocument ConfigXmlDoc { get; set; }

            // Get value of attribute with the given name in a section
            // ex: this["log", "active"]
            /// <summary>
            ///   vdvinh customize for save Common config to database
            ///   check is commmon, if true then save config to databse
            ///   last change : 20/12/2010
            /// </summary>
            public string this[string sectionName, string attributeName]
            {
                get
                {
                    if (IsCommonConfig(sectionName, attributeName))
                    {
                        CommonConfig config = CommonConfig.FindKey(sectionName, attributeName);
                        if (config != null)
                        {
                            return config.Value;
                        }
                        else
                        {
                            //Create Default
                            CommonConfig commonconfig = new CommonConfig() { sectionName = sectionName, attributeName = attributeName };
                            XmlAttribute attribute = ExecuteAttributeValue(ConfigXmlDoc, ROOTNODE, attributeName,
                                                                           SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                                           sectionName);
                            commonconfig.Value = attribute.InnerText;
                            CommonConfig.Insert(commonconfig);
                            return attribute.InnerText;
                        }
                    }
                    else
                    {
                        XmlAttribute attribute = ExecuteAttributeValue(ConfigXmlDoc, ROOTNODE, attributeName,
                                                                       SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                                       sectionName);
                        return attribute.InnerText;
                    }
                }
                set
                {
                    if (IsCommonConfig(sectionName, attributeName))
                    {
                        CommonConfig commonconfig = CommonConfig.FindKey(sectionName, attributeName);
                        if (commonconfig != null)
                        {
                            commonconfig.Value = value;
                            CommonConfig.Update(commonconfig);
                        }
                    }
                    else
                    {
                        XmlAttribute attribute = ExecuteAttributeValue(ConfigXmlDoc, ROOTNODE, attributeName,
                                                                       SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                                       sectionName);
                        attribute.InnerText = value;
                        SaveDoc(ConfigXmlDoc);
                    }
                }
            }

            // this["log", "name", "logDirectory", "attributeABC"]
            /// <summary>
            ///   vdvinh customize for save Common config to database
            ///   check is commmon, if true then save config to databse
            ///   last change : 20/12/2010
            /// </summary>
            public string this[
                string sectionName, string entryAttributeKey, string entryAttributeKeyValue, string entryAttributeName]
            {
                get
                {
                    if (IsCommonConfig(sectionName, entryAttributeKey, entryAttributeKeyValue, entryAttributeName))
                    {
                        CommonConfig config = CommonConfig.FindKey(sectionName, entryAttributeKey,
                                                                           entryAttributeKeyValue, entryAttributeName);
                        if (config != null)
                        {
                            return config.Value;
                        }
                        else
                        {
                            //Create Default
                            CommonConfig commonconfig = new CommonConfig();
                            commonconfig.sectionName = sectionName;
                            commonconfig.entryAttributeKey = entryAttributeKey;
                            commonconfig.entryAttributeKeyValue = entryAttributeKeyValue;
                            commonconfig.entryAttributeName = entryAttributeName;
                            XmlAttribute attribute = ExecuteAttributeValue(ConfigXmlDoc, ROOTNODE, entryAttributeName,
                                                                           SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                                           sectionName, ENTRY_ELEMENTNAME,
                                                                           entryAttributeKey, entryAttributeKeyValue);
                            commonconfig.Value = attribute.InnerText;
                            CommonConfig.Insert(commonconfig);
                            return attribute.InnerText;
                        }
                    }
                    else
                    {
                        XmlAttribute attribute = ExecuteAttributeValue(ConfigXmlDoc, ROOTNODE, entryAttributeName,
                                                                       SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                                       sectionName, ENTRY_ELEMENTNAME, entryAttributeKey,
                                                                       entryAttributeKeyValue);
                        return attribute.InnerText;
                    }
                }
                set
                {
                    if (IsCommonConfig(sectionName, entryAttributeKey, entryAttributeKeyValue, entryAttributeName))
                    {
                        CommonConfig commonconfig = CommonConfig.FindKey(sectionName, entryAttributeKey,
                                                                                 entryAttributeKeyValue,
                                                                                 entryAttributeName);
                        if (commonconfig != null)
                        {
                            commonconfig.Value = value;
                            CommonConfig.Update(commonconfig);
                        }
                    }
                    else
                    {
                        XmlAttribute attribute = ExecuteAttributeValue(ConfigXmlDoc, ROOTNODE, entryAttributeName,
                                                                       SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                                       sectionName, ENTRY_ELEMENTNAME, entryAttributeKey,
                                                                       entryAttributeKeyValue);
                        attribute.InnerText = value;
                        SaveDoc(ConfigXmlDoc);
                    }
                }
            }
        }

        #endregion Attribute

        #region Private    
        private const string ROOTNODE = "/";
        private const string CONFIGPATH = "/configuration/Pharmacy";
        private const string SECTION_ELEMENTNAME = "section";
        private const string SECTION_ATTRIBUTENAME = "name";
        private const string ENTRY_ELEMENTNAME = "entry";
        private const string ADD_ELEMENTNAME = "add";
        private const string ADD_ATTRIBUTEKEY = "key";
        private const string ADD_ATTRIBUTEVALUE = "value";
        private const string KEY_SKINSTYLE = "SkinStyle";
        //For Login Timeout
        private const string KEY_T0REQUESTLOGINCHECKTIME = "RequestLoginCheckTime";
        private const string KEY_T4RESPONSELOGINTIMEOUT = "ResponseLoginTimeOut";
        private const string KEY_T2ADDCHECKRESPONSESTATUS = "addCheckResponseStatus";
        private const string KEY_T3ADDRESPONSESTATUSTIMEOUT = "addResponseStatusTimeout";
        private const string KEY_T1ADDREQUESTLOGINTIMEOUT = "addRequestLoginTimeOut";
        private const string KEY_T5UPDATEACTIVETIMER = "UpdateActiveTimer";
        private const string KEY_T6UPDATEACTIVETIMEOUT = "UpdateActiveTimeOut";
        private const string PRODUCTIMAGEPATH = "ProductImagePath";
        //        
        private static string _configFilePath;

        /// <summary>
        ///   Gets a value to indicate whether the config file can be overwritten or not even when set to read-only.
        ///   NULL indicates the user does not choose yet.
        /// </summary>
        private static bool? _canOverwriteReadonlyFile;

        private Attribute _Attribute;
        private XmlDocument _Doc;
        private DateTime _LastWriteTime = DateTime.MinValue;
        private bool useCustomFormat = true;
        
        /// <summary>
        /// Constant value: "PessimisticLockingInterval".
        /// </summary>
        private const string KEY_PessimisticLockingInterval = "PessimisticLockingInterval";


        // Make sure _Doc is latest
        private XmlDocument GetLatestDoc()
        {
            if (File.Exists(_configFilePath))
            {
                FileInfo newInfo = new FileInfo(_configFilePath);
                if (_LastWriteTime != newInfo.LastWriteTime)
                {
                    //_Doc = new XmlDocument();
                    //_Doc.Load(_configFilePath);
                    XmlDocument aDoc = new XmlDocument();
                    aDoc.Load(_configFilePath); // exception may be thrown here

                    _LastWriteTime = newInfo.LastWriteTime;
                    _Doc = aDoc;
                }
            }
            //cuongnguyen, 2011:01:21 : Make sure Attributes using the latest DIOConfig file
            if (_Attribute == null)
                _Attribute = new Attribute();
            _Attribute.ConfigXmlDoc = _Doc;
            return _Doc;
        }

        #endregion

        #region static

        /// <summary>
        ///   Returns a single node with the given xmlDoc and trioCondList
        /// </summary>
        /// <param name = "xmlDoc">Represents and XML document</param>
        /// <param name = "trioCondlist">each condition are composed by element name, attribute name, and attribute value</param>
        /// <returns>Represents a single node in the XML document</returns>
        private static XmlNode GetSingleNode(XmlDocument xmlDoc, string rootElement, params string[] trioCondList)
        {
            string xPath = rootElement;
            if ((trioCondList.Length % 3) != 0)
            {
                throw new Exception("the params are invalid.");
            }
            for (int i = 0; i < trioCondList.Length; i++)
            {
                xPath += string.Format("/{0}[@{1}='{2}']", trioCondList[i], trioCondList[++i], trioCondList[++i]);
            }
            return xmlDoc.SelectSingleNode(xPath);
        }

        /// <summary>
        ///   Executes XML Node.
        /// </summary>
        /// <param name = "xmlDoc"></param>
        /// <param name = "rootElement"></param>
        /// <param name = "trioCondList"></param>
        /// <returns></returns>
        /// <author></author>
        /// <history>
        ///   2011.02.16 - ThangTran: added Xml-doc, modified catch to show original exception.
        /// </history>
        private static XmlNode ExecuteXMLNode(XmlDocument xmlDoc, string rootElement, params string[] trioCondList)
        {
            try
            {
                XmlNode xmlNode = GetSingleNode(xmlDoc, rootElement, trioCondList);

                return xmlNode;
            }
            catch (NullReferenceException ex)
            {
                throw ExceptionHelper
                    .From(ex)
                    .Message("Cannot find the node in DIOConfig file.")
                    .Data("rootElement", rootElement)
                    .DataRange("trioCondList", trioCondList)
                    .ToException();
            }
            catch (Exception ex)
            {
                throw ExceptionHelper
                    .From(ex)
                    .Message("Error occurs when reading DIOConfig file.")
                    .Data("rootElement", rootElement)
                    .DataRange("trioCondList", trioCondList)
                    .ToException();
            }
        }

        /// <summary>
        ///   Executes Attribute Value.
        /// </summary>
        /// <param name = "xmlDoc"></param>
        /// <param name = "rootElement"></param>
        /// <param name="attributeName"></param>
        /// <param name = "trioCondList"></param>
        /// <returns></returns>
        /// <author></author>
        /// <history>
        /// 2011.02.16 - ThangTran: added Xml-doc, modified catch to show original exception.
        /// </history>
        private static XmlAttribute ExecuteAttributeValue(XmlDocument xmlDoc, string rootElement, string attributeName,
                                                          params string[] trioCondList)
        {
            try
            {
                XmlNode xmlNode = ExecuteXMLNode(xmlDoc, rootElement, trioCondList);

                // ReSharper disable PossibleNullReferenceException
                return xmlNode.Attributes[attributeName];
                // ReSharper restore PossibleNullReferenceException
            }
            catch (NullReferenceException ex)
            {
                throw ExceptionHelper
                    .From(ex)
                    .Message("Cannot find the attribute in DIOConfig file.")
                    .Data("rootElement", rootElement)
                    .Data("attributeName", attributeName)
                    .DataRange("trioCondList", trioCondList)
                    .ToException();
            }
            catch (Exception ex)
            {
                throw ExceptionHelper
                    .From(ex)
                    .Message("Error occurs when reading DIOConfig file.")
                    .Data("rootElement", rootElement)
                    .Data("attributeName", attributeName)
                    .DataRange("trioCondList", trioCondList)
                    .ToException();
            }
        }

        /// <summary>
        ///   Saves DIOConfig to file.
        /// </summary>
        /// <param name = "xmlDoc"></param>
        /// <author></author>
        /// <history>
        ///   2011.01.19 - ThangTran: modified to rethrow exception.
        ///   2011.02.11 - ThangTran: added code to ask user for overwriting readonly file, task #1038.
        /// </history>
        private static void SaveDoc(XmlDocument xmlDoc)
        {
            // --- Begin parameters checking code -----------------------------
            Debug.Assert(xmlDoc != null);
            // --- End parameters checking code -------------------------------                        

            // get file attributes            
            FileAttributes fileAttributes = File.GetAttributes(_configFilePath);
            bool isReadOnly = (fileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly;            
            xmlDoc.Save(_configFilePath);

            // restore file attribute, just do this when the file attribute is actually changed
            if (isReadOnly)
            {
                File.SetAttributes(_configFilePath, fileAttributes);
            }
        }

        #endregion

        #region public

        public Attribute Attributes
        {
            get
            {
                if (_Attribute == null)
                {
                    _Attribute = new Attribute();
                    GetLatestDoc();
                }
                //cuongnguyen, 2011:01:21 : don't need Call GetLatestDoc() anytime using Attributes,
                // Make sure ConfigXmlDoc of _Attribute is latest
                //_Attribute.ConfigXmlDoc = GetLatestDoc();
                return _Attribute;
            }
        }

        /// <summary>
        ///   vdvinh customize for save Common config to database
        ///   check is commmon, if true then save config to databse
        ///   last change : 20/12/2010
        /// </summary>
        public string this[string sectionName, string entryAttributeKey, string entryAttributeKeyValue]
        {
            get
            {
                if (IsCommonConfig(sectionName, entryAttributeKey, entryAttributeKeyValue))
                {
                    CommonConfig config = CommonConfig.FindKey(sectionName, entryAttributeKey,
                                                                       entryAttributeKeyValue);
                    if (config != null)
                    {
                        return config.Value;
                    }
                    else
                    {
                        //Create Default
                        CommonConfig commonconfig = new CommonConfig();
                        commonconfig.sectionName = sectionName;
                        commonconfig.entryAttributeKey = entryAttributeKey;
                        commonconfig.entryAttributeKeyValue = entryAttributeKeyValue;
                        //XmlNode node = ExecuteXMLNode(GetLatestDoc(), ROOTNODE, SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME, sectionName, ENTRY_ELEMENTNAME, entryAttributeKey, entryAttributeKeyValue);//cuongnguyen, 2011:02:09
                        XmlNode node = ExecuteXMLNode(_Doc, ROOTNODE, SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                      sectionName, ENTRY_ELEMENTNAME, entryAttributeKey,
                                                      entryAttributeKeyValue);
                        commonconfig.Value = node.InnerText;
                        CommonConfig.Insert(commonconfig);
                        return node.InnerText;
                    }
                }
                else
                {
                    //XmlNode node = ExecuteXMLNode(GetLatestDoc(), ROOTNODE, SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME, sectionName, ENTRY_ELEMENTNAME, entryAttributeKey, entryAttributeKeyValue);//cuongnguyen, 2011:02:09
                    XmlNode node = ExecuteXMLNode(_Doc, ROOTNODE, SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                  sectionName, ENTRY_ELEMENTNAME, entryAttributeKey,
                                                  entryAttributeKeyValue);
                    return node.InnerText;
                }
            }
            set
            {
                if (IsCommonConfig(sectionName, entryAttributeKey, entryAttributeKeyValue))
                {
                    CommonConfig commonconfig = CommonConfig.FindKey(sectionName, entryAttributeKey,
                                                                             entryAttributeKeyValue);
                    if (commonconfig != null)
                    {
                        commonconfig.Value = value;
                        CommonConfig.Update(commonconfig);
                    }
                }
                else
                {
                    //XmlNode node = ExecuteXMLNode(GetLatestDoc(), ROOTNODE, SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME, sectionName, ENTRY_ELEMENTNAME, entryAttributeKey, entryAttributeKeyValue);cuongnguyen, 2011:02:09
                    XmlNode node = ExecuteXMLNode(_Doc, ROOTNODE, SECTION_ELEMENTNAME, SECTION_ATTRIBUTENAME,
                                                  sectionName, ENTRY_ELEMENTNAME, entryAttributeKey,
                                                  entryAttributeKeyValue);
                    node.InnerText = value;
                    SaveDoc(_Doc);
                }
            }
        }

        /// <summary>
        ///   vdvinh customize for save Common config to database
        ///   check is commmon, if true then save config to databse
        ///   last change : 20/12/2010
        /// </summary>
        public string this[string key]
        {
            get
            {
                if (IsCommonConfig(key))
                {
                    CommonConfig config = CommonConfig.FindKey(key);
                    if (config != null)
                    {
                        return config.Value;
                    }
                    else
                    {
                        //Create Default
                        CommonConfig commonconfig = new CommonConfig() { Key = key };
                        //XmlAttribute attribute = ExecuteAttributeValue(GetLatestDoc(), ROOTNODE + CONFIGPATH, ADD_ATTRIBUTEVALUE, ADD_ELEMENTNAME, ADD_ATTRIBUTEKEY, key);//cuongnguyen, 2011:02:09
                        XmlAttribute attribute = ExecuteAttributeValue(_Doc, ROOTNODE + CONFIGPATH, ADD_ATTRIBUTEVALUE,
                                                                       ADD_ELEMENTNAME, ADD_ATTRIBUTEKEY, key);
                        commonconfig.Value = attribute.InnerText;
                        CommonConfig.Insert(commonconfig);
                        return attribute.InnerText;
                    }
                }
                else
                {
                    //XmlAttribute attribute = ExecuteAttributeValue(GetLatestDoc(), ROOTNODE + CONFIGPATH, ADD_ATTRIBUTEVALUE, ADD_ELEMENTNAME, ADD_ATTRIBUTEKEY, key);//cuongnguyen, 2011:02:09
                    XmlAttribute attribute = ExecuteAttributeValue(_Doc, ROOTNODE + CONFIGPATH, ADD_ATTRIBUTEVALUE,
                                                                   ADD_ELEMENTNAME, ADD_ATTRIBUTEKEY, key);
                    return attribute.InnerText;
                }
            }
            set
            {
                if (IsCommonConfig(key))
                {
                    CommonConfig commonconfig = CommonConfig.FindKey(key);
                    if (commonconfig != null)
                    {
                        commonconfig.Value = value;
                        CommonConfig.Update(commonconfig);
                    }
                }
                else
                {
                    //XmlAttribute attribute = ExecuteAttributeValue(GetLatestDoc(), ROOTNODE + CONFIGPATH, ADD_ATTRIBUTEVALUE, ADD_ELEMENTNAME, ADD_ATTRIBUTEKEY, key);//cuongnguyen, 2011:02:09
                    XmlAttribute attribute = ExecuteAttributeValue(_Doc, ROOTNODE + CONFIGPATH, ADD_ATTRIBUTEVALUE,
                                                                   ADD_ELEMENTNAME, ADD_ATTRIBUTEKEY, key);
                    attribute.InnerText = value;
                    SaveDoc(_Doc);
                }
            }
        }

        public string ConfigPath
        {
            get { return _configFilePath; }
            set
            {
                _configFilePath = value;
                GetLatestDoc(); // Han Dang added in 13 Feb 2011 - Need for PDA load DioConfig.xml in webservice path.
            }
        }

        public string ProductImagePath
        {
            get { return this[PRODUCTIMAGEPATH]; }
            set { this[PRODUCTIMAGEPATH] = value; }
        }
        
        /// <summary>
        /// Gets or sets config value of Pessimistic Locking Interval.
        /// </summary>
        public int PessimisticLockingInterval
        {
            get
            {
                try
                {
                    return int.Parse(this[KEY_PessimisticLockingInterval]);
                }
                catch
                {
                    return 0;
                }
            }
            set
            {
                this[KEY_PessimisticLockingInterval] = value.ToString();
            }
        }

        /// <summary>
        ///   Call reLoad DIOConfig.xml file when nessesary.
        /// </summary>
        public void ReloadDIOConfig()
        {
            GetLatestDoc();
        }

        public string ConnectionString
        {
            get
            {
                    return string.Format(Constant.CONNNECTION_STRING,this[Constant.KEY_SERVER],this[Constant.KEY_DATABASE],this[Constant.KEY_USERID],CryptHelper.Decrypt(this[Constant.KEY_PASSWORD]));                
            }
        }

        #endregion


        #region Date Filter
        /// <summary>
        ///   Return string FromDate with format MM/dd/yyyy
        /// </summary>
        public string FromDate
        {
            get
            {
                return
                    this.Attributes[
                        Constant.DATEFILTERRANGE_SECTION_NAME, Constant.DATEFILTERRANGE_KEY_NAME, Constant.DATEFILTERRANGE_KEY_VALUE,
                        Constant.DATEFILTERRANGE_FROMDATE];
            }
            set
            {
                this.Attributes[
                    Constant.DATEFILTERRANGE_SECTION_NAME, Constant.DATEFILTERRANGE_KEY_NAME, Constant.DATEFILTERRANGE_KEY_VALUE,
                    Constant.DATEFILTERRANGE_FROMDATE] = value;
            }
        }

        /// <summary>
        ///   Return string ToDate with the format MM//dd/yyyy
        /// </summary>
        public string ToDate
        {
            get
            {
                return
                    this.Attributes[
                        Constant.DATEFILTERRANGE_SECTION_NAME, Constant.DATEFILTERRANGE_KEY_NAME, Constant.DATEFILTERRANGE_KEY_VALUE,
                        Constant.DATEFILTERRANGE_TODATE];
            }
            set
            {
                this.Attributes[
                    Constant.DATEFILTERRANGE_SECTION_NAME, Constant.DATEFILTERRANGE_KEY_NAME, Constant.DATEFILTERRANGE_KEY_VALUE,
                    Constant.DATEFILTERRANGE_TODATE] = value;
            }
        }

        public string InLastDays
        {
            get
            {
                return
                    this.Attributes[
                        Constant.DATEFILTERRANGE_SECTION_NAME, Constant.DATEFILTERRANGE_KEY_NAME, Constant.DATEFILTERRANGE_KEY_VALUE,
                        Constant.DATEFILTERRANGE_INLASTDAYS];
            }
            set
            {
                this.Attributes[
                    Constant.DATEFILTERRANGE_SECTION_NAME, Constant.DATEFILTERRANGE_KEY_NAME, Constant.DATEFILTERRANGE_KEY_VALUE,
                    Constant.DATEFILTERRANGE_INLASTDAYS] = value;
            }
        }
        #endregion
    }
}
